package com.yonyou.crm.base.attrgroup.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yonyou.crm.base.attr.entity.AttrVO;
import com.yonyou.crm.base.attr.service.AttrBBizServiceImpl;
import com.yonyou.crm.base.attr.service.AttrBizServiceImpl;
import com.yonyou.crm.base.attrgroup.entity.AttrGroupVO;
import com.yonyou.crm.base.attrgroup.entity.AttrRelationVO;
import com.yonyou.crm.common.biz.service.BaseBizServiceImpl;
import com.yonyou.crm.common.enumeration.entity.EnableStateEnum;
import com.yonyou.crm.common.enumeration.service.EnumBizServiceImpl;
import com.yonyou.crm.common.exception.CrmBusinessException;
import com.yonyou.crm.common.field.handler.FieldRelationHandler;
import com.yonyou.crm.common.field.relation.EnumFieldRelation;
import com.yonyou.crm.common.field.relation.FieldRelation;
import com.yonyou.crm.common.page.entity.Page;
import com.yonyou.iuap.context.InvocationInfoProxy;

@Service
public class AttrGroupBizServiceImpl extends BaseBizServiceImpl<AttrGroupVO> {
	
	@Autowired
	private AttrRelationBizServiceImpl arService;
	@Autowired
	private EnumBizServiceImpl enumService;
	@Autowired
	private AttrBizServiceImpl attrService;
	@Autowired
	private AttrBBizServiceImpl attrBService;
	
	/**
	 * 分页查询
	 * @param page
	 * @param paraMap
	 * @return
	 */
	public Page<AttrGroupVO> getPage(Page<AttrGroupVO> page, Map<String, Object> paraMap) {
		
		Page<AttrGroupVO> rPage = null;
		if (paraMap == null) {
			paraMap = new HashMap<String, Object>();
		}
		
		paraMap.put("tenantId", InvocationInfoProxy.getTenantid());
		
		rPage = super.pageSelect(AttrGroupVO.class, page, paraMap.keySet().toArray(new String[0]), paraMap.values().toArray(new Object[0]));
		
		trans(rPage.getData());
		
		return rPage;
		
	}
	
	@Override
	protected void beforeSaveVO(AttrGroupVO vo) {
		
		if (isExistName(null, vo.getName())) {
			throw new CrmBusinessException("属性组名称重复，保存失败！");
		}
		
		super.beforeSaveVO(vo);
		
		vo.setEnableState(EnableStateEnum.ENABLE.getValue());
	}

	@Override
	protected void afterSaveVO(AttrGroupVO vo) {
		super.afterSaveVO(vo);
		
		trans(Arrays.asList(vo));
		
		//保存属性
		arService.batchInsert(vo.getId(), vo.getAttrList());
	}

	@Override
	protected void beforeUpdateVO(AttrGroupVO vo) {
		
		if (isExistName(vo.getId(), vo.getName())) {
			throw new CrmBusinessException("属性组名称重复，保存失败！");
		}
		
		super.beforeUpdateVO(vo);
	}

	@Override
	protected void afterUpdateVO(AttrGroupVO vo) {
		super.afterUpdateVO(vo);
		
		trans(Arrays.asList(vo));
		
		//修改属性
		arService.batchUpdate(vo.getId(), vo.getAttrList());
	}
	
	/**
	 * 批量删除
	 * @param ids
	 * @return
	 */
	public String batchDelete(String[] ids) {
		
		if (ids == null || ids.length == 0) {
			return "";
		}
		
		Set<String> idSet = new HashSet<String>();
		for (String id : ids) {
			idSet.add(id);
		}
		
		int totalCount = idSet.size();
		
		StringBuffer reasonBuffer = new StringBuffer("【");
		
		//是否产品或产品分类引用
		List<Map<String, Object>> attrList = getAGByProductOrPrdtype(idSet.toArray(new String[0]));
		
		if (attrList != null && attrList.size() > 0) {
			
			for (Map<String, Object> map : attrList) {
				
				reasonBuffer.append(map.get("name"));
				reasonBuffer.append(",");

				String typeId = map.get("id").toString();
				//被产品或产品分类引用不能删除
				idSet.remove(typeId);
			}
			reasonBuffer.delete(reasonBuffer.length()-1, reasonBuffer.length());
			reasonBuffer.append("】属性组被产品或产品分类引用，不可删除！");
		}
		
		int successCount = idSet.size();
		int failCount = totalCount - idSet.size();
		String message = failCount == 0 ? "成功" + successCount + "条。" : "成功" + successCount + "条，失败" + failCount + "条。\n失败原因：" + reasonBuffer.toString();
		
		if (successCount > 0) {
			
			arService.batchDelete(idSet.toArray(new String[0]));
			super.batchDeleteByIDs(AttrGroupVO.class, idSet.toArray(new String[0]));
		}
		
		return message;
		
	}
	
	/**
	 * 批量停启用属性
	 * @param ids
	 * @param enableState
	 */
	public void batchUpdateEnableState(String[] ids, Integer enableState) {
		
		Map<String, Object> enableParaMap = new HashMap<String, Object>();
		enableParaMap.put("ids", ids);
		enableParaMap.put("enableState", enableState);
		enableParaMap.put("enableUserId", new Long(InvocationInfoProxy.getParameter("id")));
		enableParaMap.put("enableTime", new Date());
				
		dao.updateSql(AttrGroupVO.class, "batchUpdateEnableState", enableParaMap);
	}
	
	/**
	 * 被产品或产品分类引用的属性组列表
	 * @param ids
	 * @return
	 */
	public List<Map<String, Object>> getAGByProductOrPrdtype(String[] ids) {
		return dao.selectList(AttrGroupVO.class, "getAGByProductOrPrdtype", ids);
	}
	
	/**
	 * 是否被产品或产品分类引用
	 * @param attrGroupId
	 * @return
	 */
	public boolean isCitedByProductOrPrdtype(Long attrGroupId) {
		return dao.countAll(AttrGroupVO.class, "getCountByProductOrPrdtype", attrGroupId) > 0;
	}
	
	/**
	 * 名称是否存在
	 * @param id
	 * @param name
	 * @return
	 */
	public boolean isExistName(Long id, String name) {
		Map<String, Object> paraMap = new HashMap<String, Object>();
		paraMap.put("id", id);
		paraMap.put("name", name);
		paraMap.put("tenantId", InvocationInfoProxy.getTenantid());
		return dao.countAll(AttrGroupVO.class, "getCountByName", paraMap) > 0;
	}
	
	/**
	 * 参照列表
	 * @param paraMap
	 * @return
	 */
	public List<AttrGroupVO> getRefList(Map<String, Object> paraMap) {

		if (paraMap == null) {
			paraMap = new HashMap<String, Object>();
		}
		
		paraMap.put("tenantId", new Long(InvocationInfoProxy.getTenantid()));
		
		return dao.selectVoList(AttrGroupVO.class, "getRefList", paraMap);
	}
	
	/**
	 * 分页参照列表
	 * @param page
	 * @param paraMap
	 * @return
	 */
	public Page<AttrGroupVO> getRefPage(Page<AttrGroupVO> page, Map<String, Object> paraMap) {

		if (paraMap == null) {
			paraMap = new HashMap<String, Object>();
		}
		
		paraMap.put("tenantId", new Long(InvocationInfoProxy.getTenantid()));
		
		return dao.pageSelect(AttrGroupVO.class, page, "getRefPage", "countRefPage", paraMap);
	}
	
	/**
	 * 属性组名称翻译
	 * @param ids
	 * @return
	 */
	public Object selectFieldsByIds(Object[] ids) {
		Map<String, Object> para = new HashMap<String, Object>();
		para.put("ids", ids);
		return dao.selectList(AttrGroupVO.class, "selectFieldsByIds", para);
	}
	
	/**
	 * 获得属性组选中的属性
	 * @param attrGroupId
	 * @return
	 */
	public Map<String, Object> getCheckedAttr(Long attrGroupId) {
		
		Map<String, Object> rMap = new HashMap<String, Object>();

		rMap.put("allList", attrService.getRefList());
		rMap.put("checkedList", dao.selectStrList(AttrGroupVO.class, "getCheckedAttr", attrGroupId));
		
		return rMap;
	}

	/**
	 * 根据属性组id获得属性列表
	 * @param attrGroupId
	 * @return
	 */
	public List<AttrVO> getAttrListByAGId(Long attrGroupId) {
		return dao.selectVoList(AttrGroupVO.class, "getAttrListByAGId", attrGroupId);
	}
	
	/**
	 * 获得属性组选中的属性值
	 * @param attrGroupId
	 * @param attrId
	 * @return
	 */
	public Map<String, Object> getCheckedAttrValue(Long attrGroupId, Long attrId) {
		
		Map<String, Object> paraMap = new HashMap<String, Object>();
		paraMap.put("attrGroupId", attrGroupId);
		paraMap.put("attrId", attrId);
		
		Map<String, Object> rMap = new HashMap<String, Object>();

		rMap.put("allList", attrBService.getRefList(attrId));
		rMap.put("checkedList", dao.selectList(AttrGroupVO.class, "getCheckedAttrValue", paraMap));
		
		return rMap;
	}
	
	private List<AttrGroupVO> trans(List<AttrGroupVO> voList) {
		
		if (voList != null && voList.size() > 0) {
			
			List<FieldRelation<AttrGroupVO>> relations = new ArrayList<FieldRelation<AttrGroupVO>>();
			relations.add(new EnumFieldRelation<AttrGroupVO>(AttrGroupVO.class, "enableState", "enableStateName", enumService, "enable_state"));
			new FieldRelationHandler<AttrGroupVO>().handler(voList, relations);
			
			for (AttrGroupVO agVO : voList) {
				
				if (agVO != null && agVO.getAttrList() != null && agVO.getAttrList().size() > 0) {
					
					List<Long> attrIdList = new ArrayList<Long>();
					for (AttrRelationVO arVO : agVO.getAttrList()) {
						attrIdList.add(arVO.getAttrId());
					}
					agVO.setAttrNames(attrService.getNamesByIds(attrIdList.toArray(new Long[0])));
				}
			}
		}

		return voList;
	}
	
	/**
	 * 移动端分页参照列表
	 * @param page
	 * @param paraMap
	 * @return
	 */
	public List<AttrGroupVO> getRefervaluesForApp(Page<AttrGroupVO> page, Map<String, Object> paraMap) {

		if (paraMap == null) {
			paraMap = new HashMap<String, Object>();
		}
		
		paraMap.put("tenantId", new Long(InvocationInfoProxy.getTenantid()));
		
		Page<AttrGroupVO> pageVO=  dao.pageSelect(AttrGroupVO.class, page, "selectRefervalues", "countRefervalues", paraMap);
		
		List<AttrGroupVO> voList = pageVO.getData();
		trans(voList);
		return voList;
	}
	
}
